/*
 * JobChooser.cuh
 *
 *  Created on: Aug 9, 2013
 *      Author: jaime
 */

#ifndef JOBCHOOSER_CUH_
#define JOBCHOOSER_CUH_
#include "../SATSolver/Configs.cuh"

/**
 * The enum ChoosingStrategy is used to define the strategy
 * the chooser will use. They are:
 *
 *   * DISTRIBUTE_JOBS_PER_THREAD: Generate as many jobs as defined in JOBS_PER_THREAD
 * for each thread (if possible, or as many as possible)
 * 	 * UNIFORM: Generate jobs using as many variables as defined in UNIFORM_NUMBER_OF_VARS (if possible,
 * or as many as possible)
 *
 */
enum ChoosingStrategy
{
	DISTRIBUTE_JOBS_PER_THREAD, UNIFORM

};

#include "VariableChooser.cuh"
#include "../SATSolver/JobsQueue.cuh"

class JobChooser
{
public:
	//virtual ~JobChooser() = 0;
	virtual void evaluate() = 0;
	virtual void getJobs(JobsQueue & queue) = 0;
	virtual int get_number_of_jobs() = 0;
	virtual bool is_evaluated() = 0;

private:
	virtual void addJobs(Lit* fixed_lits, int number_fixed_lits, JobsQueue & queue) = 0;
};

class MaxClauseJobChooser : public JobChooser {
public:
	MaxClauseJobChooser(vector <Clause> * formula, int number_of_variables, int number_of_dead_variables,
			int number_of_threads, int number_of_blocks);
	MaxClauseJobChooser(vector <Clause> * formula, int number_of_variables, int number_of_dead_variables,
			int threads, int number_of_blocks, ChoosingStrategy strategy);
	~MaxClauseJobChooser();
	void evaluate();
	void getJobs(JobsQueue & queue);
	int get_number_of_jobs();
	bool is_evaluated();

private:
	VariableChooser variable_chooser;
	int number_of_working_variables;
	bool evaluated;
	int number_of_threads;
	int number_of_blocks;
	Var* chosen_variables;
	int variables_per_job;
	ChoosingStrategy strategy;

	void addJobs(Lit* fixed_lits, int number_fixed_lits, JobsQueue & queue);
	void evalVarPerJobs();
	void evalVarPerJobsDistribute();
	void evalVarPerJobsUniform();

};

#endif /* JOBCHOOSER_CUH_ */
